package site.xuqing.autohelper;

import android.accessibilityservice.AccessibilityService;

import site.xuqing.autohelper.bean.StepBean;
import site.xuqing.autohelper.bean.StepCallbackBean;
import site.xuqing.autohelper.listener.OnStepListener;
import site.xuqing.autohelper.util.StepExecutor;
import site.xuqing.autohelper.util.StringUtil;

/**
 * 自定义步骤继承该类，实现自己的步骤自定义
 *
 * @author XuQing
 */
public abstract class StepScript {
    private final Object STEP_SCRIPT_LOCK = new Object();
    private String currentScreenActivityClassName;
    private String currentNodeActivityClassName;
    
    /**
     * 执行自定义步骤
     * 当步骤中有要跳转界面的地方，需要调用lock方法
     *
     * @param service        服务
     * @param stepBean       当前步骤
     * @param stepExecutor   工具类
     * @param onStepListener 回调
     * @throws Exception 抛出异常
     */
    public abstract void doStep(AccessibilityService service, StepBean stepBean, StepExecutor stepExecutor, OnStepListener onStepListener) throws Exception;
    
    /**
     * 锁，该方法需要永华在有界面跳转时，等待界面跳转完成时调用
     *
     * @param currentNodeActivityClassName 用户传入的className
     * @throws InterruptedException 异常
     */
    public void lock(String currentNodeActivityClassName) throws InterruptedException {
        if (!StringUtil.isEmptyString(currentNodeActivityClassName) && !currentNodeActivityClassName.equals(currentScreenActivityClassName)) {
            this.currentNodeActivityClassName = currentNodeActivityClassName;
            synchronized(STEP_SCRIPT_LOCK) {
                System.out.println("StepScript lock:触发了一次锁");
                STEP_SCRIPT_LOCK.wait();
            }
        }
    }
    
    /**
     * 解锁，该方法不需要手动调用
     *
     * @param currentScreenActivityClassName 系统显示的当前界面的className
     */
    public void unlock(String currentScreenActivityClassName) {
        this.currentScreenActivityClassName = currentScreenActivityClassName;
        if (!StringUtil.isEmptyString(currentNodeActivityClassName)) {
            synchronized(STEP_SCRIPT_LOCK) {
                if (currentScreenActivityClassName.equals(currentNodeActivityClassName)) {
                    System.out.println("StepScript lock:触发了一次解锁");
                    STEP_SCRIPT_LOCK.notifyAll();
                }
            }
        }
    }
    
    /**
     * 同步执行，一般用于需要在回调里面获取用户设置的问题
     * @param onStepListener OnStepListener
     * @param stepCallbackBean StepCallbackBean
     * @return StepCallbackBean
     * @throws InterruptedException Exception
     */
    public StepCallbackBean doSyncCallback(final OnStepListener onStepListener, final StepCallbackBean stepCallbackBean) throws InterruptedException {
        final StepCallbackBean[] stepCallbackBeans = new StepCallbackBean[1];
        synchronized(STEP_SCRIPT_LOCK) {
            System.out.println("doSyncCallback lock:触发了一次锁");
            new Thread() {
                @Override
                public void run() {
                    StepCallbackBean callback = null;
                    try {
                        callback = onStepListener.onSyncCallback(stepCallbackBean);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    if (callback != null) {
                        System.out.println("doSyncCallback lock:触发了一次解锁");
                        stepCallbackBeans[0] = callback;
                        synchronized(STEP_SCRIPT_LOCK) {
                            STEP_SCRIPT_LOCK.notifyAll();
                        }
                    }
                }
            }.start();
            STEP_SCRIPT_LOCK.wait();
        }
        return stepCallbackBeans[0];
    }
    
    /**
     * 异步执行，一般用户给用户下发信息
     * @param onStepListener OnStepListener
     * @param stepCallbackBean stepCallbackBean
     */
    public void onAsyncCallback(final OnStepListener onStepListener, final StepCallbackBean stepCallbackBean) {
        new Thread() {
            @Override
            public void run() {
                if (onStepListener != null) {
                    try {
                        onStepListener.onAsyncCallback(stepCallbackBean);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
    }
}
